package com.laiketui.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laiketui.common.mapper.UserMapper;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.domain.user.User;
import com.laiketui.order.api.dto.*;
import com.laiketui.order.api.enums.*;
import com.laiketui.order.api.params.OrderInfoParams;
import com.laiketui.order.api.params.mch.MchOrderInfoParams;
import com.laiketui.order.api.params.store.ExamineOrderParams;
import com.laiketui.order.domain.*;
import com.laiketui.order.entity.ExamineOrderDetailEntity;
import com.laiketui.order.mapper.OrderMapper;
import com.laiketui.order.mapper.OrderOfflineExamineMapper;
import com.laiketui.order.mapper.OrderParentMapper;
import com.laiketui.order.mapstruct.*;
import com.laiketui.order.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ExamineOrderServiceImpl extends ServiceImpl<OrderOfflineExamineMapper, OrderOfflineExamine>
        implements ExamineOrderService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderParentService orderParentService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private OrderOfflineExamineService orderOfflineExamineService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderOfflineExamineMapper offlineExamineMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMessageService orderMessageService;


    @Override
    public String examineOrder(ExamineOrderParams params) {
        OrderOfflineExamine offlineExamine = new OrderOfflineExamine();
        offlineExamine.setBalancePayAmount(params.getBalancePayAmount());
        offlineExamine.setExamineImg(params.getExamineImg());
        offlineExamine.setExamineMessage(params.getExamineMessage());
        Date now = new Date();
        offlineExamine.setExamineTime(now);
        offlineExamine.setReceiveTime(params.getReceiveTime());
        offlineExamine.setExamineType(params.getExamineType());
        offlineExamine.setFailType(params.getFailType());
        offlineExamine.setOfflinePayAmount(params.getOfflinePayAmount());
        offlineExamine.setOrderParentNo(params.getOrderParentNo());
        offlineExamine.setPayBank(params.getPayBank());
        offlineExamine.setPayMan(params.getPayMan());
        offlineExamine.setPayType(params.getPayType());
        offlineExamine.setRemark(params.getRemark());
        offlineExamine.setSettlementType(params.getSettlementType());
        offlineExamine.setTotalPrice(params.getTotalPrice());
        boolean save = orderOfflineExamineService.save(offlineExamine);
        if(!save){
            throw new LaiKeAPIException("审核失败");
        }
        //根据审核状态修改订单状态
        updateParentOrderStatus(offlineExamine.getExamineType(),offlineExamine.getOrderParentNo());
        return params.getOrderParentNo();
    }

    @Override
    public ExamineOrderDetailDTO examineInfo(OrderInfoParams params) {
        ExamineOrderDetailEntity entity;
        OrderOfflineExamine offlineExamine = null;
        entity = offlineExamineMapper.selectExamineOrderInfo(params);
        if(Objects.isNull(entity)){
            entity = new ExamineOrderDetailEntity();
        }
        OrderParent orderParent = orderParentService.getOrderParent(params.getOrderParentNo());
        entity.setSource(1);
        User user = new User();
        user.setUser_id(orderParent.getUserId());
        user = userMapper.selectOne(user);
        if(user == null){
            throw new LaiKeAPIException("不存在该用户");
        }
        //获取上一次审核不通过凭证
        LambdaQueryWrapper<OrderOfflineExamine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOfflineExamine::getOrderParentNo,params.getOrderParentNo());
        wrapper.eq(OrderOfflineExamine::getExamineType,OrderExamineTypeEnum.NO_PASS);
        wrapper.orderByDesc(OrderOfflineExamine::getExamineTime);
        List<OrderOfflineExamine> offlineExamineList = offlineExamineMapper.selectList(wrapper);
        if(offlineExamineList.size() > 0){
            offlineExamine = offlineExamineList.get(0);
        }
        if(offlineExamine != null){
            entity.setExamineImg(offlineExamine.getExamineImg());
        }

        Integer signatoryType = user.getSignatory_type();
        if(signatoryType != null && (signatoryType == 2 || signatoryType == 3)){
            entity.setPayMan(user.getCompany_name());
        }else{
            entity.setPayMan(user.getUser_name());
        }
        ExamineOrderDetailDTO dto = ExamineOrderDetailMapstructMapper.INSTANCE.toDTO(entity);
        return dto;
    }

    @Override
    public List<OrderOfflineExamineDTO> examineList(OrderInfoParams params) {
        LambdaQueryWrapper<OrderOfflineExamine> wrapper = new LambdaQueryWrapper();
        wrapper.eq(OrderOfflineExamine::getOrderParentNo,params.getOrderParentNo());
        List<OrderOfflineExamine> examineList = offlineExamineMapper.selectList(wrapper);
        List<OrderOfflineExamineDTO> dtOs = OrderOfflineExamineMapstructMapper.INSTANCE.toDTOs(examineList);
        return dtOs;
    }

    @Override
    public ExamineOrderDTO orderDetails(MchOrderInfoParams params) {
        Order order = orderService.findByOrderNo(params.getOrderNo());
        ExamineOrderDTO dto = OrderMapstructMapper.INSTANCE.toExamineDTO(order);
        List<OrderDetail> details = orderDetailService.findByOrderNo(params.getOrderNo());
        List<OrderDetailDTO> dtOs = OrderDetailMapstructMapper.INSTANCE.toDTOs(details);
        dto.setDetails(dtOs);

        Set<String> brandSet = new HashSet<>();
        dtOs.forEach(s ->{
            brandSet.add(s.getBrandName());
        });
        String brandStr = String.join(",", brandSet);
        dto.setBrandName(brandStr);

        List<Order> orders = new ArrayList<>();
        orders.add(order);
        //获取渠道和来源
        String channel = warehouseService.getChannel();
        dto.setChannel(channel);
        dto.setSourceName(OrderSourceEnum.getDecByCode(dto.getSource()));

        //获取服务商
        User user = new User();
        user.setUser_id(dto.getUserId());
        user = userMapper.selectOne(user);
        if(user != null){
            dto.setProvince(user.getProvince());
            dto.setCity(user.getCity());
            dto.setUserName(user.getSignatory_name());
//            dto.setUserName(user.getUser_name());
        }

        List<OrderMessage> messages = orderMessageService.listByOrderNo(order.getOrderNo());
        List<OrderMessageDTO> dtoMessages = OrderMessageMapstructMapper.INSTANCE.toDTOs(messages);
        dto.setMessages(dtoMessages);
        return dto;
    }

    @Override
    public OrderOfflineExamine passOrderInfo(OrderInfoParams params) {
        OrderOfflineExamine offlineExamine = null;
        LambdaQueryWrapper<OrderOfflineExamine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOfflineExamine::getOrderParentNo,params.getOrderParentNo());
        wrapper.eq(OrderOfflineExamine::getPayType, OrderExamineTypeEnum.PASS.getCode());
        List<OrderOfflineExamine> list = this.list(wrapper);
        if(list.size() > 0){
            offlineExamine = list.get(0);
        }
        return offlineExamine;
    }

    @Override
    public String returnWaitPay(String orderParentNo) {
        OrderParent orderParent = orderParentService.getOrderParent(orderParentNo);
        Integer status = orderParent.getStatus();
        if(!status.equals(OrderParentStatusEnum.WAIT_CHECK.getCode())){
            throw new LaiKeAPIException("订单状态错误");
        }
        orderParent.setStatus(OrderParentStatusEnum.WAIT_PAY.getCode());
        orderParentService.updateByOrderParentNo(orderParentNo, orderParent);
        return orderParentNo;
    }


    public void updateParentOrderStatus(int examineType, String orderParentNo){
        LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper();
        wrapper.eq(OrderParent::getStatus, OrderParentStatusEnum.WAIT_CHECK.getCode());
        wrapper.eq(OrderParent::getOrderParentNo, orderParentNo);
        OrderParent orderParent = new OrderParent();
        //审核通过修改为待发货,否则回到待付款
        if(examineType == OrderExamineTypeEnum.PASS.getCode()){
            orderParent.setStatus(OrderParentStatusEnum.WAIT_SEND.getCode());
            boolean update = orderParentService.update(orderParent, wrapper);
            if(!update){
                throw new LaiKeAPIException("修改状态失败");
            }
            //修改所有子单为待确认
            updateOrderAndDetailStatusToConfirm(orderParentNo);
        }else{
            orderParent.setStatus(OrderParentStatusEnum.WAIT_PAY.getCode());
            orderParentService.update(orderParent,wrapper);
        }
    }

    public void updateOrderAndDetailStatusToConfirm(String orderParentNo){
        Order order = new Order();
        order.setStatus(OrderStatusEnum.WAIT_CHECK.getCode());
        Date now = new Date();
        order.setUpdateTime(now);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOrderParentNo, orderParentNo);
        orderService.update(order, wrapper);
    }

}
